import axios from "axios";
import { ElMessage, ElMessageBox } from "element-plus";
import envConfig from "./getEnvConfig";
import { Session } from "@/utils/storage";
import useAuths from "@/hooks/useAuths"; // get token from cookie

const { VITE_BASE_URL } = envConfig;
// 配置新建一个 axios 实例
const service = axios.create({
  baseURL: VITE_BASE_URL, // api 的 base_url
  timeout: 60000, // 请求超时时间
  headers: { "Content-Type": "application/json" },
  hideerror: false, //是否在底层显示错误信息
});

// 添加请求拦截器
service.interceptors.request.use(
  (config) => {
    // 在发送请求之前做些什么 token
    const { getToken } = useAuths();
    const token = getToken();
    if (token) {
      config.headers["Authorization"] = `Bearer ${token}`;
    }
    if (Session.get("tenantId")) {
      config.headers["TenantId"] = Session.get("tenantId");
    }
    return config;
  },
  (error) => {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 是否正在刷新的标记
let isRefreshing = false;

// 重试队列，每一项将是一个待执行的函数形式
let requests = [];

// 添加响应拦截器
service.interceptors.response.use(
  (response) => {
    const { getToken, refreshToken, clearStorage } = useAuths();
    if (response.config.isFileRet) {
      let type = response.headers["content-type"];
      if (type.indexOf("application/octet-stream") === -1) {
        return Promise.reject(response);
      } else {
        return response;
      }
    }
    const res = response.data;
    if (res.statusCode !== 200) {
      if (res.statusCode == 1001) {
        //刷新accessToken并重新请求。
        const config = response.config;
        if (!isRefreshing) {
          isRefreshing = true;
          return refreshToken()
            .then(
              () => {
                let accessToken = getToken();
                //  这里有个小问题  当在重试中 如果接口报错 就会直接跳转到登录页  需要后端配合
                // 已经刷新了accessToken，将所有队列中的请求进行重试
                setTimeout(() => {
                  requests.forEach((cb) => cb(accessToken));
                  requests = [];
                }, 200);
                return service(config);
              },
              () => {}
            )
            .catch(() => {})
            .finally(() => {
              isRefreshing = false;
            });
        } else {
          // 正在刷新token，将返回一个未执行resolve的promise
          // 保存函数 等待执行
          // 吧请求都保存起来 等刷新完成后再一个一个调用
          return new Promise((resolve) => {
            if (response.config.url !== `/Account/login/refresh_token`) {
              // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
              requests.push((token) => {
                config.headers["Authorization"] = `Bearer ${token}`;
                resolve(service(config));
              });
            }
          });
        }
      } else if (res.statusCode == 1002) {
        //refleshToken过期,重新登录
        ElMessageBox.alert("你已被登出，请重新登录", "提示", {})
          .then(() => {
            clearStorage();
          })
          .catch(() => {});
        return Promise.reject(res);
      } else {
        if (!response.config.hideerror) {
          ElMessage({
            showClose: true,
            message: res.message || "",
            type: "error",
            duration: 2 * 1000,
          });
        }
        return Promise.reject(new Error(res.message || "Error"));
      }
    } else {
      if (!res.status) {
        //请求成功但处理失败
        ElMessage({
          showClose: true,
          message: res?.data?.message ? res?.data?.message : res.message,
          type: "error",
          duration: 2 * 1000,
        });
        return Promise.reject(new Error("业务错误"));
      } else {
        if (res.data === null || res.data === undefined) {
          return res;
        }
        return res.data;
      }
    }
  },
  (error) => {
    // 对响应错误做点什么
    let msg = "";
    if (error.message.indexOf("timeout") != -1) {
      msg = "网络超时";
    } else if (error.message == "Network Error") {
      msg = "网络连接错误";
    } else {
      if (error?.response?.data) {
        msg = error?.response.statusText;
      } else if (error?.response) {
        msg = "接口路径找不到";
      } else {
        msg = error.message || "请求错误";
      }
    }
    ElMessage({
      showClose: true,
      message: msg || "",
      type: "error",
      duration: 2 * 1000,
    });
    return Promise.reject(error);
  }
);

// 导出 axios 实例
export default service;
